<?php

namespace Shared\LocalSyntaxSpecific\Metadata;

/**
 * 
 * @author Jordan Minchev <j.minchev@object.bg>
 * @copyright (c) 2014, ASPECT.BG Ltd.
 */
class Parser {

	/**
	 *
	 * @var \Shared\LocalSyntaxSpecific\Entity\LocalSyntaxSpecificI 
	 */
	private $Entity;

	/**
	 *
	 * @var string
	 */
	private $classname;

	/**
	 *
	 * @var \Doctrine\ORM\EntityManager 
	 */
	private $EntityManager;

	/**
	 * @var \Doctrine\Common\Annotations\Reader
	 */
	private $Reader;

	/**
	 * @var \Shared\LocalSyntaxSpecific\Metadata\EntityMetadata 
	 */
	private $EntityMetadata;

	/**
	 *
	 * @var array 
	 */
	private $columnTypes = array('string', 'text');

	/**
	 * @var array 
	 */
	private static $cache = array();

	/**
	 * 
	 * @param \Shared\LocalSyntaxSpecific\Entity\LocalSyntaxSpecificI $Entity
	 */
	public function __construct(\Shared\LocalSyntaxSpecific\Entity\LocalSyntaxSpecificI $Entity) {
		$this->Entity = $Entity;
		$this->classname = \Doctrine\Common\Util\ClassUtils::getRealClass(get_class($Entity));

		$this->EntityManager = \Shared\Application::instance()->getEntityManager();
		$this->Reader = \Shared\Application::instance()->getAnnotationReader();
	}

	/**
	 * @return \Shared\LocalSyntaxSpecific\Metadata\EntityMetadata
	 */
	public function parse() {
		$this->EntityMetadata = $this->getFromLocalCache();
		if (!$this->EntityMetadata) {
			$ClassMetadataFactory = $this->EntityManager->getMetadataFactory();
			$ClassMetadata = $ClassMetadataFactory->getMetadataFor($this->classname);

			$plainTextProperties = array();
			$htmlProperties = array();

			foreach ($ClassMetadata->getReflectionClass()->getProperties() as $Property) {
				$ColumnAnnotation = $this->Reader->getPropertyAnnotation($Property, '\Doctrine\ORM\Mapping\Column');
				if ($ColumnAnnotation && in_array($ColumnAnnotation->type, $this->columnTypes)) {
					$HTMLAnnotation = $this->Reader->getPropertyAnnotation($Property, '\Shared\LocalSyntaxSpecific\Annotations\HTML');
					if ($HTMLAnnotation) {
						$htmlProperties[] = $Property->name;
					} else {
						$plainTextProperties[] = $Property->name;
					}
				}
			}
			$this->EntityMetadata = new \Shared\LocalSyntaxSpecific\Metadata\EntityMetadata($this->classname, $htmlProperties, $plainTextProperties);
			$this->cache($this->EntityMetadata);
		}
		return $this->EntityMetadata;
	}

	/**
	 * @return \Shared\LocalSyntaxSpecific\Metadata\EntityMetadata
	 */
	private function getFromLocalCache() {
		if (array_key_exists($this->classname, self::$cache)) {
			return self::$cache[$this->classname];
		}
	}

	/**
	 * @param \Shared\LocalSyntaxSpecific\Metadata\EntityMetadata $Object
	 */
	private function cache($Object) {
		self::$cache[$this->classname] = $Object;
	}

}
